package com.style.study.juc.c_017_threadpool;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author zhangsan
 * @date 2021/4/28 22:50
 */
public class SipnLock {

    static Unsafe UNSAFE;
    static final long A_OFFEST;
    static final long LOCK_OFFEST;

    static int a = 0;
    static int lock = 1;

    static {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            UNSAFE = (Unsafe) theUnsafe.get(null);  // 反射拿到UNSAFE
            Class<SipnLock> clazz = SipnLock.class;
            A_OFFEST = UNSAFE.staticFieldOffset(clazz.getDeclaredField("a"));   // 通过UNSAFE拿到这个类的静态变量的偏移量
            LOCK_OFFEST = UNSAFE.staticFieldOffset(clazz.getDeclaredField("lock"));   // 通过UNSAFE拿到这个类的静态变量的偏移量
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    // 自旋锁
    public static void lock() {
        for (;;) {
            if (UNSAFE.compareAndSwapInt(SipnLock.class, LOCK_OFFEST, 1, 0)) {
                break;
            }
            Thread.yield();
        }
    }

    public static void unlock() {
        lock = 1;
    }

    public static void increment() {
        lock();
        a++;
        unlock();
    }


    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(29);
        for (int i = 0; i < 1000000; i++) {
            pool.execute(SipnLock::increment);
        }
        pool.shutdown();
        try {
            pool.awaitTermination(1, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(a);
    }

}
